/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Services.UsuarioService;

import Services.AppService;
import dataBase.HibernateUtil;
import exeptions.GeneralException;
import exeptions.MsgException;
import java.util.ArrayList;
import java.util.List;
import mapeos.Grupo;
import mapeos.Usuario;
import mapeos.Usuariogrupo;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.Restrictions;
import org.hibernate.exception.ConstraintViolationException;
import utils.StringUtils;

/**
 *
 * @author IvanPianetti
 */
public class UsuarioService implements IUsuarioService {

    private static IUsuarioService unUsuario;
    private static Usuario usuarioActual = null;

    public static IUsuarioService getInstance() {
        if (unUsuario == null || !(unUsuario instanceof UsuarioService)) {
            unUsuario = new UsuarioService();
        }
        return unUsuario;
    }

    public static Usuario getUsuarioActual() {
        return usuarioActual;
    }

    public List<Usuario> getAll() throws GeneralException {
        List<Usuario> usuarios = null;
        Session s = HibernateUtil.currentSession();
        try {
            Transaction t = s.beginTransaction();
            usuarios = (List<Usuario>) s.createCriteria(Usuario.class).list();
        } catch (HibernateException he) {
            throw new GeneralException(MsgException.getMsgException("General.ErrorAlConsultar", he));
        } finally {
            if (s.isOpen()) {
                s.close();
            }
        }
        return usuarios;
    }

    /**
     * Obtiene todos los Usuarios que pertenezcan a un Grupo
     * @param pGrupo
     * @return
     * @throws GeneralException
     */
    public List<Usuario> getAllByGrupo(Grupo pGrupo) throws GeneralException {
        List<Usuario> listaUsuario = new ArrayList<Usuario>();
        List<Usuariogrupo> listaUsuariosGrupos = AppService.getInstance().getUsuarioGrupoService().getAllByGrupo(pGrupo);
        for (Usuariogrupo usuariogrupo : listaUsuariosGrupos) {
            listaUsuario.add(usuariogrupo.getUsuario());
        }
        return listaUsuario;
    }

    public Usuario logIn(String user, String clave) throws GeneralException {
        usuarioActual = null;
        Session s = HibernateUtil.currentSession();
        try {
            Transaction t = s.beginTransaction();
            usuarioActual = (Usuario) s.createCriteria(Usuario.class).
                    add(Restrictions.eq("usuarioUsuario", user)).
                    add(Restrictions.eq("claveUsuario", clave)).uniqueResult();
        } catch (HibernateException he) {
            throw new GeneralException(MsgException.getMsgException("General.ErrorAlConsultar", he));
        } finally {
            if (s.isOpen()) {
                s.close();
            }
            return usuarioActual;
        }
    }

    public Usuario getByMail(String pMail) throws GeneralException {
        Usuario user = null;
        Session s = HibernateUtil.currentSession();
        try {
            Transaction t = s.beginTransaction();
            user = (Usuario) s.createCriteria(Usuario.class).
                    add(Restrictions.like("mailUsuario", pMail).ignoreCase()).
                    uniqueResult();
        } catch (HibernateException he) {
            throw new GeneralException(MsgException.getMsgException("General.ErrorAlConsultar", he));
        } finally {
            if (s.isOpen()) {
                s.close();
            }
            return user;
        }
    }

    /**
     * @param pUsuario
     * @throws GeneralException
     */
    public void insert(Usuario pUsuario) throws GeneralException {
        if (this.isUsuarioValido(pUsuario)) {
            Session s = HibernateUtil.currentSession();
            try {
                Transaction t = s.beginTransaction();
                s.save(pUsuario);
                t.commit();
                AppService.getInstance().getArchivoService().crearCarpetaHome(pUsuario);
            } catch (ConstraintViolationException he) {
                throw new GeneralException(MsgException.getMsgException("Usuario.Existe", he));
            } catch (HibernateException he) {
                throw new HibernateException(he);
            } finally {
                if (s.isOpen()) {
                    s.close();
                }
            }
        }
    }

    public void update(Usuario pUsuario) throws GeneralException {
        if (this.isUsuarioValido(pUsuario)) {
            Session s = HibernateUtil.currentSession();
            try {
                Transaction t = s.beginTransaction();
                s.update(pUsuario);
                t.commit();
            } catch (HibernateException he) {
                throw new HibernateException(he);
            } finally {
                if (s.isOpen()) {
                    s.close();
                }
            }
        }
    }

    private boolean isUsuarioValido(Usuario pUsuario) throws GeneralException {
        if (pUsuario.getNombreUsuario() != null & !pUsuario.getNombreUsuario().equalsIgnoreCase("")) {
            if (StringUtils.isEmailValido(pUsuario.getMailUsuario())) {
                if (pUsuario.getClaveUsuario() != null & pUsuario.getClaveUsuario().length() >= 5) {
                    return true;
                } else {
                    throw new GeneralException(MsgException.getMsgException("Usuario.ClaveCorta"));
                }
            } else {
                throw new GeneralException(MsgException.getMsgException("Usuario.MailInvalido"));
            }
        } else {
            throw new GeneralException(MsgException.getMsgException("Usuario.NombreInvalido"));
        }
    }
}